#ifndef DEFMOD_ABSTRACT_MODULE_HPP
#define DEFMOD_ABSTRACT_MODULE_HPP

#include "Module/DefModConfig.hpp"
#include <string>

namespace Module
{

/// \ingroup Module
/// \brief It provides the interface to be implemented by any module that should be included in the application.
/// \details
///		The module should register, when initializes, various elements, like UI commands, storages, model entities, etc.
class MODULE_API AbstractModule
{
public:
	virtual ~AbstractModule() { }

	/// \brief It initializes the module.
	/// \details
	///		In this implementation, it is a template method design, so this method calls the various register* methods, 
	///		allowing subclasses to overwrite only the registrations that are needed.
	virtual void initialize();

	/// \brief It gets the unique identifier of the module.
	virtual const std::string& uid() const = 0;

protected:
	/// \brief The subclasses should overwrite this method if there are other supported storages that can be used.
	virtual void registerStorages();

	/// \brief The subclasses should overwrite this method if there are other supported CASE entities that can be used.
	virtual void registerEntities();

	/// \brief The subclasses should overwrite this method if there are other storage configuration types that can be used.
	virtual void registerStorageCfgTypes();

	/// \brief The subclasses should overwrite this method if there are other user interface commands that can be used.
	virtual void registerUICommands();
};

} // namespace Module

#endif // DEFMOD_ABSTRACT_MODULE_HPP
